#include "vpdecodeaudiothread.h"
#include <QDebug>
#include "vpentrance.h"
VpDecodeAudioThread::VpDecodeAudioThread()
{
    m_stop = false;
}

bool VpDecodeAudioThread::start(AVCodecContext *codec_ctx, VpPacketQueue *audio_pkt_queue, VpFrameQueue *audio_fme_queue)
{
    m_stop   = false;
    bool res = true;
    if(!codec_ctx)
        res  = false;
    else
    {
        thread decode_audio_th(work, this, codec_ctx, audio_pkt_queue, audio_fme_queue);
        decode_audio_th.detach();
    }
    return res;
}

void VpDecodeAudioThread::stop()
{
    m_stop = true;
}

void VpDecodeAudioThread::work(VpDecodeAudioThread* vp_decode_audio_th, AVCodecContext *codec_ctx, VpPacketQueue *audio_pkt_queue, VpFrameQueue *audio_fme_queue)
{
    qDebug()<<"decode audio thread start";
    VpEntrance::s_RUNNING_THREAD_NUM += 1;
    int ret                           = -1;
    while(!vp_decode_audio_th->m_stop)
    {
        {
            unique_lock<mutex> lock(audio_fme_queue->m_mutex);
            while(audio_fme_queue->get_size() > MAX_ADUIO_FRAME_NUM && !vp_decode_audio_th->m_stop)
                audio_fme_queue->m_cond.wait_for(lock, chrono::milliseconds(20));
        }

        VpPacket pkt;
        VpFrame srcframe;
        do
        {
            ret = avcodec_receive_frame(codec_ctx, srcframe.m_frame);
            if(ret == 0)
            {
                srcframe.setSerial(audio_fme_queue->serial());
                srcframe.m_pts = (srcframe.m_frame->pts == AV_NOPTS_VALUE) ? NAN : srcframe.m_frame->pts * av_q2d(audio_fme_queue->m_tb);
                srcframe.m_duration = (srcframe.m_frame->duration == AV_NOPTS_VALUE) ? NAN : srcframe.m_frame->duration * av_q2d(audio_fme_queue->m_tb);
                audio_fme_queue->push(srcframe);
            }
            else if(ret == AVERROR_EOF)
            {
                break;
            }
        }while(ret != AVERROR(EAGAIN));
        pkt = audio_pkt_queue->pop();
        if(pkt.serial() != audio_fme_queue->serial())
        {
            audio_fme_queue->flush_queue();
            audio_fme_queue->setSerial(pkt.serial());
        }
        ret = avcodec_send_packet(codec_ctx, pkt.m_packet);
        if (ret == AVERROR_EOF) {
            avcodec_flush_buffers(codec_ctx);
        }else if(ret == AVERROR(EAGAIN)){
            continue;
        }else if(ret < 0) {
            qDebug()<<"error"<<ret;
            break;
        }
    }
    {
        lock_guard<mutex> lock(vp_decode_audio_th->m_mutex);
        VpEntrance::s_RUNNING_THREAD_NUM -= 1;
        qDebug()<<"decode audio thread end";
    }
    return;
}
